#pragma once
#include "Lockqueue.h"
#include "Singleton.h"
#include <sys/stat.h>
#include <string>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>

// 改进的日志宏定义，添加了安全检查
#define LOGD(logmsgformat, ...)                                                              \
    do                                                                                       \
    {                                                                                        \
        Logger &logger = Logger::getInstance();                                              \
        if (logger.GetLogLevel() >= Logger::DEBUG)                                           \
        {                                                                                    \
            logger.WriteLog(Logger::DEBUG, __FILE__, __LINE__, logmsgformat, ##__VA_ARGS__); \
        }                                                                                    \
    } while (0)

#define LOGI(logmsgformat, ...)                                                             \
    do                                                                                      \
    {                                                                                       \
        Logger &logger = Logger::getInstance();                                             \
        if (logger.GetLogLevel() >= Logger::INFO)                                           \
        {                                                                                   \
            logger.WriteLog(Logger::INFO, __FILE__, __LINE__, logmsgformat, ##__VA_ARGS__); \
        }                                                                                   \
    } while (0)

#define LOGW(logmsgformat, ...)                                                             \
    do                                                                                      \
    {                                                                                       \
        Logger &logger = Logger::getInstance();                                             \
        if (logger.GetLogLevel() >= Logger::WARN)                                           \
        {                                                                                   \
            logger.WriteLog(Logger::WARN, __FILE__, __LINE__, logmsgformat, ##__VA_ARGS__); \
        }                                                                                   \
    } while (0)

#define LOGE(logmsgformat, ...)                                                              \
    do                                                                                       \
    {                                                                                        \
        Logger &logger = Logger::getInstance();                                              \
        if (logger.GetLogLevel() >= Logger::ERROR)                                           \
        {                                                                                    \
            logger.WriteLog(Logger::ERROR, __FILE__, __LINE__, logmsgformat, ##__VA_ARGS__); \
        }                                                                                    \
    } while (0)

#define LOGF(logmsgformat, ...)                                                              \
    do                                                                                       \
    {                                                                                        \
        Logger &logger = Logger::getInstance();                                              \
        if (logger.GetLogLevel() >= Logger::FATAL)                                           \
        {                                                                                    \
            logger.WriteLog(Logger::FATAL, __FILE__, __LINE__, logmsgformat, ##__VA_ARGS__); \
        }                                                                                    \
    } while (0)

// 改进的日志系统类
class Logger : public Singleton<Logger>
{
    friend class Singleton<Logger>;

public:
    enum LogLevel
    {
        LEVEL_INIT = 0,
        DEBUG,
        INFO,
        WARN,
        ERROR,
        FATAL,
        LEVEL_COUNT
    };

    static const char *s_level[LEVEL_COUNT];

    // 设置日志级别
    void SetLogLevel(LogLevel level);

    // 设置日志文件最大大小（字节）
    void SetMaxFileSize(long int maxSize);

    // 设置日志文件路径前缀
    void SetLogPath(const std::string &path);

    // 获取当前日志级别
    LogLevel GetLogLevel() const;

    // 写入日志的模板函数
    template <typename... Args>
    void WriteLog(LogLevel level, const char *file, int line, const char *format, Args... args);

    // 停止日志系统
    void Stop();

private:
    Logger();
    ~Logger();

    // 禁用拷贝构造和赋值
    Logger(const Logger &) = delete;
    Logger &operator=(const Logger &) = delete;

    // 日志写入线程函数
    void WriteLogThread();

    // 检查并轮转日志文件
    void CheckAndRotateLogFile();

    // 获取当前日志文件名
    std::string GetCurrentLogFileName() const;

    // 格式化日志消息
    std::string FormatLogMessage(LogLevel level, const char *file, int line, const std::string &msg);

    // 创建目录的辅助函数
    void CreateDirectoryIfNotExists(const std::string &path);

private:
    std::atomic<LogLevel> m_logLevel{DEBUG};    // 当前日志级别
    std::atomic<long int> m_maxFileSize{10000}; // 单个日志文件最大大小
    std::atomic<int> m_fileIndex{1};            // 当前日志文件索引
    std::string m_logPath{"./log/"};            // 日志文件路径前缀

    LockQueue<std::string> m_logQueue; // 日志消息队列

    FILE *m_filePtr{nullptr};                    // 当前日志文件指针
    std::atomic<bool> m_fileIsOpen{false};       // 文件是否已打开
    std::atomic<bool> m_directoryCreated{false}; // 目录是否已创建
    std::mutex m_fileMutex;                      // 文件操作互斥锁

    std::atomic<bool> m_running{true};       // 日志线程运行标志
    std::thread m_writeThread;               // 日志写入线程
    std::condition_variable m_stopCondition; // 停止条件变量
    std::mutex m_stopMutex;                  // 停止互斥锁
};

// 模板函数实现
template <typename... Args>
void Logger::WriteLog(LogLevel level, const char *file, int line, const char *format, Args... args)
{
    if (!m_running.load())
    {
        return;
    }

    try
    {
        // 使用 snprintf 安全地格式化字符串
        constexpr int BUFFER_SIZE = 2048;
        char buffer[BUFFER_SIZE] = {0};

        int result = snprintf(buffer, BUFFER_SIZE - 1, format, args...);
        if (result < 0)
        {
            // 格式化失败
            return;
        }

        std::string message(buffer);
        std::string formattedMsg = FormatLogMessage(level, file, line, message);

        // 将消息放入队列
        m_logQueue.Push(formattedMsg);
    }
    catch (const std::exception &e)
    {
        // 记录格式化错误，但不抛出异常
        std::string errorMsg = FormatLogMessage(ERROR, __FILE__, __LINE__,
                                                std::string("Log formatting error: ") + e.what());
        m_logQueue.Push(errorMsg);
    }
}